package com.hsmpay.yl8583.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;

import org.apache.log4j.Logger;

public class Field {
	static Logger log = Logger.getLogger(Field.class);
	public  static enum Type{
		ASCII,BCD,BINARY
	}
	public static enum Format{
		LLVAR,LLLVAR,hhmmss,MMDD,YYMM,MMDDhhmmss
	}
	private String name;
	private int len;
	private Format format;
	private Type type;
    private int filedNumber;
	private byte[] value;
	
	
	public void valueof(Date value,String fromat) throws UnsupportedEncodingException{
		if(fromat.equals("hhmmss")){
			this.valueof(String.format("%1$tH%1$tM%1$tS",value).getBytes("US-ASCII"));
		}
		else if(fromat.equals("MMDD")){
			this.valueof(String.format("%1$tm%1$tm",value).getBytes("US-ASCII"));
		}
		else if(fromat.equals("YYMM")){
			this.valueof(String.format("%1$ty%1$tm",value).getBytes("US-ASCII"));
		}
		else if(fromat.equals("MMDDhhmmss")){
			this.valueof(String.format("%1$tm%1$tm%1$tH%1$tM%1$tS",value).getBytes("US-ASCII"));
		}
	}
	public void valueof(double value,int length) throws UnsupportedEncodingException{
		this.valueof(String.format("%1$0"+length+"d",(int)value*100).getBytes("US-ASCII"));
	}
	public void valueof(int value,int length) throws UnsupportedEncodingException{
		this.valueof(String.format("%1$0"+length+"d",value).getBytes("US-ASCII"));
	}
	public void valueof(String value) throws UnsupportedEncodingException{
		//this.valueof(value.getBytes("US-ASCII"));
		this.valueof(value.getBytes("GBK"));
	}
	public void valueof(String hex,int len){
		byte[] value=PackageUtil.BCD2ASCII(PackageUtil.hexStringToByte(hex), len);
		this.valueof(value);
	}
	public void valueof(ByteArrayInputStream s) throws Exception{
		if(format!=null&&format.name()=="LLVAR"){
    		byte []byte_len= new byte[1];
    		s.read(byte_len);
    		this.len=Integer.parseInt(new String(PackageUtil.BCD2ASCII(byte_len,2),"ASCII"));
    	}
    	else if(format!=null&&format.name()=="LLLVAR"){
    		byte []byte_len= new byte[2];
    		s.read(byte_len);
    		this.len=Integer.parseInt(new String(PackageUtil.BCD2ASCII(byte_len,4),"ASCII"));
    	}
		log.debug(this.filedNumber+"域长度:"+len);
    	switch(type){
			case BCD:
				if(filedNumber==55 || filedNumber==62)
				{
					this.value= new byte[len];
				}else{
					this.value= new byte[(len+1)/2];//正常处理
				}
				break;
			case ASCII:
				this.value= new byte[len];
				break;
			case BINARY:
				this.value= new byte[len/8];
				break;
		}
		s.read(value);
	}
	
	public void valueof(byte[] asc_value){
		switch(type){
			case BCD:
				this.setValue(PackageUtil.ASCII2BCD(asc_value));
				if(filedNumber==55 || filedNumber==62 || filedNumber==53)
				{
					this.len=asc_value.length/2;
				}else{
					this.len=asc_value.length;
				}
				break;
			case ASCII:
				if(filedNumber==63)
				{
					this.setValue(PackageUtil.ASCII2BCD(asc_value));
					this.len=asc_value.length/2;
				}else{
					this.setValue(asc_value);
					this.len=asc_value.length;
				}
				break;
			case BINARY:
				this.setValue(asc_value);
				this.len=asc_value.length;
				break;
		}
		//this.len=asc_value.length;
		
	}
	public byte[] toByte(){
		ByteArrayOutputStream writer=null;
		try{
			writer=new ByteArrayOutputStream();
        	if(format==null||format.name().equals("hhmmss")||
        	format.name().equals("MMDD")||format.name().equals("YYMM")){
        		writer.write(value);
			}
			else if(format.name().equals("LLVAR")){
				byte[] byte_len=PackageUtil.INT2BCD(this.len, 1);
				writer.write(byte_len);
				writer.write(value);
			}
        	else if(format.name().equals("LLLVAR")){
    			byte[] byte_len=PackageUtil.INT2BCD(this.len, 2);
    			writer.write(byte_len);
    			writer.write(value);
        	}
			if (writer.toByteArray()==null)throw new NullPointerException("field's vlaue is null.");
			
			return writer.toByteArray();
		}catch(Exception ex){
			ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
		}finally{
			if(writer!=null){
				try{
					writer.close();
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}
	}
	public void init(){		
	}
	
	public int getLen() {
		return len;
	}
	public void setLen(int len) {
		this.len = len;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Format getFormat() {
		return format;
	}
	public void setFormat(Format format) {
		this.format = format;
	}
	public Type getType() {
		return type;
	}
	public void setType(Type type) {
		this.type = type;
	}
	public int getFiledNumber() {
		return filedNumber;
	}
	public void setFiledNumber(int filedNumber) {
		this.filedNumber = filedNumber;
	}
	public byte[] getValue() {
		return value;
	}
	public void setValue(byte[] value) {
		this.value = value;
	}
}
